/*
 *  Copyright (C) 2010 Glauco
 * 
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 * 
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 * 
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.balisunrise.swing.transaction.panel;

import java.awt.Component;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import javax.swing.JPanel;
import org.balisunrise.builder.BuilderException;
import org.balisunrise.common.FieldLayout;
import org.balisunrise.swing.builder.FieldLayoutBuilder;

/**
 * Painel dos campos da entidade.
 *
 * @author Glauco
 */
public class FieldsPanel extends JPanel{

    /**
     * Antigos valores da propriedade enabled dos componentes.
     */
    private Map<Component,Boolean> oldEnabled;

    /**
     * Antigos valores da propriedade focusable dos componentes.
     */
    private Map<Component,Boolean> oldFocusable;

    /**
     * Lista de componentes do painel.
     */
    private List<FieldLayout> fieldLayouts;

    /**
     * Contrutor do layout do painel dos campos de uma entidade.
     */
    private FieldLayoutBuilder layoutBuilder;

    /**
     * Contrutor do painel de campos de uma entidade.<br>
     * É criado o layout com os componentes e o FieldLayoutBuilder recebidos
     * por parametro.
     *
     * @param panelFields Lista dos componentes que representão os compos de
     * uma entidade.
     * 
     * @param layoutBuilder FieldLayoutBuilder, para construir o layout do
     * painel.
     */
    public FieldsPanel(List<FieldLayout> fieldLayouts,
            FieldLayoutBuilder layoutBuilder) {
        this.fieldLayouts = fieldLayouts;
        this.layoutBuilder = layoutBuilder;
        createLayout();
    }

    /**
     * Retorna a lista de componentes do painel.
     * @return
     */
    public List<FieldLayout> getFieldLayouts() {
        return fieldLayouts;
    }

    /**
     * Atribui a lista dos componentes do painel.<br>
     * Ao alterar a lista de componentes é necessário o método createLayout para
     * redesenhar o layout do painel.
     * @param panelFields
     */
    public void setFieldLayouts(List<FieldLayout> fieldLayouts) {
        this.fieldLayouts = fieldLayouts;
    }

    /**
     * Cria Layout para o painel a partir da lista de componentes do objeto.<br>
     * Este método é executado ao criar uma instancia do FieldsPanel.<br>
     * Ao alterar a lista de componentes é necessário chamar este método para
     * redesenhar o layout do painel.
     */
    public void createLayout(){
        try{
            // cria Layout
            layoutBuilder.create(this, fieldLayouts);
        }catch(BuilderException be){
            System.out.println(
                    "Erro em FieldsPanel ao criar layout.\n"+
                    be.getMessage());
        }
    }

    @Override
    public void setEnabled(boolean enabled) {
        
        if(enabled && oldEnabled != null){
            for (Component component : getComponents()) {
                Boolean cEnabled = oldEnabled.get(component);
                if(cEnabled != null)
                    component.setEnabled(cEnabled);
            }
            oldEnabled = null;
            return ;
        }

        if(!enabled && oldEnabled == null){
            oldEnabled = new 
                    IdentityHashMap<Component,Boolean>(getComponents().length);
            for (Component component : getComponents()) {
                Boolean cEnabled = component.isEnabled();
                oldEnabled.put(component, cEnabled);
                component.setEnabled(false);
            }
        }

        super.setEnabled(enabled);
    }

    @Override
    public void setFocusable(boolean focusable) {

        if(focusable && oldFocusable != null){
            for (Component component : getComponents()) {
                Boolean cFocusable = oldFocusable.get(component);
                if(cFocusable != null)
                    component.setFocusable(cFocusable);
            }
            oldFocusable = null;
            return ;
        }

        if(!focusable && oldFocusable == null){
            oldFocusable = new
                    IdentityHashMap<Component,Boolean>(getComponents().length);
            for (Component component : getComponents()) {
                Boolean cFocusable = component.isFocusable();
                oldFocusable.put(component, cFocusable);
                component.setFocusable(false);
            }
        }

        super.setFocusable(focusable);
    }
}
